********************************************
* Crude Stata installer program
* Tore Olsen 2012
********************************************
clear
set more off
cap program drop bunch_count_installer
program define bunch_count_installer
qui {
    * logistics:
    local pwd = c(pwd)
    
    * Determining operating system:
    
	local dirsep = "/"
	if "`c(os)'"=="Windows" {
	    local os_flavor = "Windows"
	    local dirsep    = "\"
	}
	else {
	    local os_flavor = "Unix"
	    local dirsep    = "/"   
	}
	
	* Determining ado PLUS directory
		local plus = c(sysdir_plus)
		
		noi di _newline _newline _newline _newline _newline _newline _newline _newline _newline _newline _newline 
		noi di _newline _newline _newline _newline _newline _newline _newline _newline _newline _newline _newline 
		noi di _newline "This program will try to install necessary files for doing bunching calculations similar to those in"
		noi di  _newline "                    Chetty, Friedman, Olsen and Pistaferri"
		noi di  _newline "Adjustment Costs, Firm Responses, and Micro vs. Macro Labor Supply Elasticities:"
		noi di  _newline "                       Evidence from Danish Tax Records"
		noi di  _newline "           The Quarterly Journal of Economics, 2011, 126 (2): 749-804"
		noi di  _newline _newline _newline "Stata reports that your ado/plus directory should be" _newline 
		noi di as red `"`plus'"' _newline
		
		qui capture cd `"`plus'"'
		local rc = _rc
		
		if `rc'==0{
		 	noi di as green "Do you want to:" _newline
		 	noi di as green "a. Install the bunching files in your ado/plus directory."
		 	noi di as green "b. Exit" _newline
		 	noi di as red "Please type a or b, then hit return/enter" _newline _request(answer) 
		 	if lower(trim("$answer"))~="a"{
		 		noi di "Thank you. Goodbye"
		 		exit
		 	}
		 	else {
		 		noi di "Thank you."
		  		local install = 1
		 	}
		}
		else if `rc'==170 {
			noi di as green "However, Stata also reports that your ado/plus directory is " _newline 
			noi di as red "       NOT AVAILABLE" 
			noi di as green _newline "This might be because it has not been created yet in your file system." _newline 
			noi di as green "Do you want to:"
			noi di as green "a. Create it (if possible) and install bunching files at"  _newline `"    `plus' (overwriting existing files with same names) ?"'
			noi di as green "b. Install the files elsewhere?"
			noi di as green "c. Not install the files at all?" 
			noi di as red _newline "Please type a, b, or c and hit enter/return" _newline _request(answer) 
		 	if lower(trim(`"$answer"'))=="a"{
		 	     noi di as green "Thank you." _newline _newline "Creating directories as necessary ..."
		 	     bunch_count_cd, dir(`"`plus'"') mkdir(1) quiet(1)
		 	     noi di as green `"`plus'"' _newline "should be created and available now."
		 	     local install = 1
		 	}
		 	else if lower(trim(`"$answer"'))=="b"{
		 		noi di as green "Google how to change your Stata personal ado path."
		 		noi di as green "A good place to change the adopath is in a profile.do file"
		 		noi di as green "that gets loaded everytime you start Stata."
		 		noi di as green _newline "Thank you. Come back when you are ready."
		 		exit
		 	}
		 	else {
		 		noi di "Thank you. Goodbye"
		 		exit
		 	}
		 }
	    * if `rc'~=0 & `rc'~=170 
	    else {
			noi di "something is wrong. I don't know what. Sorry."
			exit 110
		}
		
		if `install'==1 {
		if `"`os_flavor'"'=="Windows" {
			noi di as red _newline "PLEASE DRAG THE installer.do TO THE STATA COMMAND LINE (sic)"
			noi di as green "and hit enter/return. (Alternatively you can type the whole path to the folder where it is stored" 
			noi di as green "such as C:\users\Joe\Downloads\bunch_count\ and then hit enter/return) " _newline _request(location) 
			if length(trim(`"$location"'))~=0 {
				local location = subinstr(`"$location"',`"doedit ""',"",.)
				local location = subinstr(`"`location'"',`"doedit "',"",.)
			    local location = subinstr(`"`location'"',`"\Installer.do""',"",.)
				local location = subinstr(`"`location'"',`"\installer.do""',"",.)
				local location = subinstr(`"`location'"',`"/Installer.do""',"",.)
				local location = subinstr(`"`location'"',`"/installer.do""',"",.)
			    local location = subinstr(`"`location'"',`"\Installer.do"',"",.)
				local location = subinstr(`"`location'"',`"\installer.do"',"",.)
				local location = subinstr(`"`location'"',`"/Installer.do"',"",.)
				local location = subinstr(`"`location'"',`"/installer.do"',"",.)
				noi di as green "Thank you." _newline _newline `"Copying files from"' _newline `"`location'"' _newline "to" _newline `"`plus' ..."'
				local lng = length(`"`location'"')
				if (substr(`"`location'"',`lng',1)=="/") | (substr(`"`location'"',`lng',1)=="\") {
					local lng2=`lng'-1
					local location=substr(`"`location'"',1,`lng2')
				}

				qui cd "`location'"
				local lng = length(`"`plus'"')
				if (substr(`"`plus'"',`lng',1)=="/") | (substr(`"`plus'"',`lng',1)=="\") {
					local lng2=`lng'-1
					local plus=substr(`"`plus'"',1,`lng2')
				}
				local from = "`location'"+"`dirsep'"+"bunch_count.ado"
				local to   = "`plus'"+"`dirsep'"+"bunch_count.ado"
			    copy `"`from'"' `"`to'"', replace
				local from = "`location'"+"`dirsep'"+"bunch_count.sthlp"
				local to   = "`plus'"+"`dirsep'"+"bunch_count.sthlp"
				copy `"`from'"' `"`to'"', replace
				noi di as green _newline "The relevant files should now have been copied to your ado directory"
				noi di as green _newline "You should now be ready use the bunch_count command."
				noi di _newline "Thank you. Goodbye."
			}
			else {
				noi di "Thank you. Good bye"
			}
			
			
		}
		else {
			noi di as red _newline "PLEASE DRAG THE installer.do TO THE STATA COMMAND LINE (sic)"
			noi di "and hit enter/return. (Alternatively you can type the whole path to the folder" 
			noi di "such as ~/Downloads/bunch_count/ and then hit enter/return) " _newline _request(location) 
			if length(trim(`"$location"'))~=0 {
				local location = subinstr(`"$location"',`"doedit ""',"",.)
				local location = subinstr(`"`location'"',`"doedit "',"",.)
			    local location = subinstr(`"`location'"',`"\Installer.do""',"",.)
				local location = subinstr(`"`location'"',`"\installer.do""',"",.)
				local location = subinstr(`"`location'"',`"/Installer.do""',"",.)
				local location = subinstr(`"`location'"',`"/installer.do""',"",.)
			    local location = subinstr(`"`location'"',`"\Installer.do"',"",.)
				local location = subinstr(`"`location'"',`"\installer.do"',"",.)
				local location = subinstr(`"`location'"',`"/Installer.do"',"",.)
				local location = subinstr(`"`location'"',`"/installer.do"',"",.)
				noi di as green "Thank you." _newline _newline `"Copying files from"' _newline `"`location'"' _newline "to" _newline `"`plus' ..."'
				local lng = length(`"`location'"')
				if (substr(`"`location'"',`lng',1)=="/") | (substr(`"`location'"',`lng',1)=="\") {
					local lng2=`lng'-1
					local location=substr(`"`location'"',1,`lng2')
				}

				qui cd "`location'"
				local lng = length(`"`plus'"')
				if (substr(`"`plus'"',`lng',1)=="/") | (substr(`"`plus'"',`lng',1)=="\") {
					local lng2=`lng'-1
					local plus=substr(`"`plus'"',1,`lng2')
				}
				local from = "`location'"+"`dirsep'"+"bunch_count.ado"
				local to   = "`plus'"+"`dirsep'"+"bunch_count.ado"
			    copy `"`from'"' `"`to'"', replace
				local from = "`location'"+"`dirsep'"+"bunch_count.sthlp"
				local to   = "`plus'"+"`dirsep'"+"bunch_count.sthlp"
				copy `"`from'"' `"`to'"', replace
				noi di as green _newline "The relevant files should now have been copied to your ado directory"
				noi di as green _newline "You should now be ready use the bunch_count command."
				noi di _newline "Thank you. Goodbye."

			}
			else {
				noi di "Thank you. Good bye"
			}
		
		}
		}
		
		qui cd `"`pwd'"'
		
}
		
end


*******************************************************************************
* bunch_count_cd program 
* Tore Olsen 2008
* Problem:    Unix uses "/" to separate directories, while Windows and DOS use "\"
*             Unix example: /home/user/documents/data.dta
*             Windows example: C:\user\documents\data.dta
*             If we want the same programs to run on Windows and Unix
*             - without changing the path specifications -
*             then this poses a challenge for STATAs cd command.
*
* Solution:   Parse user specified directory for hierachical separators
*             and change them to fit.
*
* Extra:      Option to allow the creation of specified directories, if they 
*             do not exist prior to issuing issuing the bunch_count_cd commnand.
*
*             bunch_count_cd, dir("c:\users\tore\test\example") mkdir(1)
*
*             will create every folder along the path if they do not already 
*             exist, whereas a regular cd statement would fail if the folders 
*             along the path did not exist. However:
*             - use mkdir(1) option with caution!
* 
* Note:       On Unix based systems incl Mac OSX, the program makes the   
*             assumption that "\ " in the directory name is meant to 
*             indicate a space in a folder-name.
*
* Limitations: Currently the program does not support specification of network 
*              options in the file path. Also it does not handle Windows
*              formatted paths to network drives on Unix flavored systems
*              and vice versa.
*
*******************************************************************************
cap program drop bunch_count_cd    
program define bunch_count_cd
version 10
syntax, dir(string) [quiet(integer 1) mkdir(integer 0) heroic(integer 0) set_trace(integer 0)]
    
    * LOGISTICS
		* Set_trace option
		if `set_trace'!=0{
			set trace on
			set tracedepth `set_trace'
		}
		
        * Set quiet option 
        if `quiet'==1 local qui "qui"
        
        * Get operating system flavor
        if (c(os)=="Unix")|(c(os)=="MacOSX") {
        	local os_flavor = "Unix"
			local dirsep "/"
        }
        else {
        	local os_flavor = "Windows"
			local dirsep "\"
        }
        local CIFS_SMB_issue=0
    
    * TRY REGULAR cd COMMAND
    `qui' cap cd `"`dir'"'
    if _rc==0 {
        * We're done
        exit
    }
    * FIX UNIX SPECIFICATION WITH "\ " INDICATING SPACE
    else {
        local dir = subinstr(`"`dir'"',"\ "," ",.)
        `qui' cap cd `"`dir'"'
         if _rc==0 {
            * We're done
            exit
        }     
    }
    
    * FIX UNIX PATH ON WINDOWS
    else if (`"`os_flavor'"'=="Windows") {
        * Fix for home dir specification
        if substr(`"`dir'"',1,11)=="~/Documents" {                  
            local dir = "C:\Documents and Settings\"+`"`c(username)'"'+"\My Documents\"'+substr(`"`dir'"',13,.)
        }
        else if substr(`"`dir'"',1,1)=="~" {
            local dir = "C:\Documents and Settings\"+`"`c(username)'\"'+substr(`"`dir'"',3,.)
        }
        * change Unix "/" to Windows "\"
        local dir = subinstr(`"`dir'"',"/","\",.)
        * change Unix "SMB://" to Windows "//"
        if (upper(substr(`"`dir'"',1,4))=="SMB:") {
            local dir = substr(`"`dir'"',5,.)
        }
        * change Unix "CIFS://" to Windows "//"
        else if (upper(substr(`"`dir'"',1,5))=="CIFS:") {
            local dir = substr(`"`dir'"',6,.)
        }
        `qui' cap cd `"`dir'"'
        if _rc==0 {
            * We're done
            exit
        } 
 
    } 
    * FIX WINDOWS PATH ON UNIX
    else if (`"`os_flavor'"'=="Unix") {
        * CHANGE WINDOWS "\" TO UNIX "/"
        local dir = subinstr(`"`dir'"',"\","/",.)
        * DEALING WITH WINDOWS USER PATH
        * And recalling that we just changed all "\" to "/"
        local windows_user = "C:/Documents and Settings/"+`"`c(username)'"' 
        if (strpos(`"`dir'"',`"`windows_user'"')~=0){
            local n = length(`"`windows_user'"')+1
            local dir = "~"+substr(`"`dir'"',`n',.)
            if upper(substr(`"`dir'"',1,14))=="~/MY DOCUMENTS"{
                local dir = "~/Documents"+substr(`"`dir'"',15,.) 
            }
        }
        * TRYING IT OUT
        `qui' cap cd `"`dir'"'
        if _rc==0 {
            * We're done
            exit
        } 
        * Dealing with "\\" on Windows 
        * corresponding to either CIFS:// or SMB:// on Unix
        if (substr(`"`dir'"',1,2))=="//" {
            local CIFS_SMB_issue=1
            local fix1 = "CIFS:"+`"`dir'"' 
            `qui' cap cd `"`fix1'"'
            if _rc==0 {
                * We're done
                exit
            }
            local fix2 = "SMB:"+`"`dir'"' 
            `qui' cap cd `"`fix2'"'
            if _rc==0 {
                * We're done
                exit
            }
        * end if statement regarding "\\" on Windows.
        }
    * end if os_flavor=Unix statement
    } 
    
   
    if `mkdir' == 0 {
        di as error "could not change to "`"`dir'"'". Perhaps set option of mkdir=1 in bunch_count_cd"
        noi lookup _rc
        exit 110
    }
    * Trying to create hierachy given by `dir'
    else {
    

                
        *SETTING PREFIX TO PATH            
        *UNIX
        if `"`os_flavor'"'=="Unix" {
            local dir0 ="/"
            if substr(`"`dir'"',1,1)=="~" {
                local dir0 =""  
            }
            else if upper(substr(`"`dir'"',1,4))=="SMB:" {
                local dir0 = "SMB://"
                local dir  = substr(`"`dir'"',7,.))
            }
            else if upper(substr(`"`dir'"',1,5))=="CIFS:" {
                local dir0 = "CIFS://"
                local dir  = substr(`"`dir'"',8,.))
            }
        }
        * WINDOWS
        else {
            local dir0 = ""
            if substr(`"`dir'"',1,2) == "\\" {
                local dir0 = "\\"
                local dir  = substr(`"`dir'"',3,.))
            }
            else if substr(`"`dir'"',1,1) == "\" {
                local dir0 = "\"
                local dir  = substr(`"`dir'"',2,.))
            }
        }
                        
        * GETTING PATH HIERACHY
        local i = 0
        tokenize `"`dir'"', parse(`"`dirsep'"')
        while `"`1'"'~="" {
            if `"`1'"'~=`"`dirsep'"' {
                local j         = `i' + 1
                local subdir`j' = `"`1'"'
                local dir`j'    = `"`dir`i''"'+`"`1'"'+`"`dirsep'"'
                local i         = `j'
             }
             macro shift
        }
                    
                    
                        
        * FINDING HIGHEST LEVEL THAT STATA CAN CHANGE TO
        local end=0
        forval k    = `i'(-1)0{
            if `end'  == 0 {
                `qui' cap cd `"`dir`k''"'
                if _rc==0 {
                    local level = `k'
                    local end = 1
                }
                * Dealing with CIFS/SMB issues 
                * that arises when Windows paths 
                * are used on Unix
                else if `CIFS_SMB_issue'==1 {
                    local fix1 = "CIFS:/"+`"`dir'"' 
                    `qui' cap cd `"`fix1'"')
                    if _rc==0 {
                        local level = `k'
                        local end = 1
                    }
                    else {
                        local fix2 = "SMB:/"+`"`dir'"' 
                        `qui' cap cd `"`fix1'"')
                        if _rc==0 {
                            local level = `k'
                            local end = 1
                        }
                    }
                * end CIFS_SMB issue fix
                }
            * end: if `end'  == 0 statement
            }
        * end: forval k    = `i'(-1)0 statement
        }
            
        * CREATING SUBDIRECTORIES FROM THIS LEVEL AND UP
        local level  = `level' + 1
        forval k     = `level'/`i' {
            `qui' cap mkdir `"`subdir`k''"'
            if _rc~=170& _rc~=0 {
               noi lookup _rc
               exit 110
            }   
            `qui' cd `"`subdir`k''"'
        }
    * end if mkdir=1 statement                     
    }
    end
    
	

bunch_count_installer	
		
exit
